from .base_strategy import BaseStrategy
import backtrader as bt
import backtrader.indicators as btind
import indicator.MyTTIndicator as Mytt
import indicator.myzhibiao as mmm


###
# 55日线突破策略
# 使用4h级别, 唐齐安通道（55）, 当收盘价突破上轨, 则开多单, 使用atr100, 波动率进行仓位管理
# 止损使用开仓价格1atr, 止损, 止盈则是5atr 或者 最高的回落3atr 移动止损
# 
# #
class MyStrategy(BaseStrategy):
    params = (
        ('donchian_period', 55),  # 唐齐安通道周期
        ('atr_period', 14),      # ATR计算周期
        ('risk_exposure', 0.01),  # 风险暴露比例 (2%)
        ('stop_loss_mult', 2.0),  # 止损倍数 (2倍ATR)
        ('trail_mult', 3.0),      # 回撤止盈倍数 (3倍ATR)
        ('take_profit_mult', 5.0), # 盈利止盈倍数 (5倍ATR)
    )

 
    def __init__(self):
        super().__init__()

        # 初始化指标
        self.donchian_high = btind.Highest(self.data.high(-1), period=self.p.donchian_period)
        self.donchian_low = btind.Lowest(self.data.low(-1), period=self.p.donchian_period)
        

        
        self.atr = btind.ATR(self.data, period=self.p.atr_period)
        
         # 跟踪变量
        self.order = None

        self.stop_loss_price = 0 # 止损价格
        self.take_profit_price = 0 # 止盈价格

        # 绘图相关的参数
        self.donchian_high.plotinfo.plot = True # 启用绘图，默认是启用的
        self.donchian_high.plotinfo.subplot = False  # 禁用子图（绘制在主图）
        self.donchian_low.plotinfo.subplot = False
                # 自定义悬停显示格式
        self.donchian_high.plotinfo.plotfmt = 'Donchian High: %.2f'  # 显示 2 位小数
        self.donchian_low.plotinfo.plotfmt = 'Donchian Low: %.2f'

    def start(self):
        pass

    def notify_order(self, order):
        super().notify_order(order)
        if order.status in [order.Submitted, order.Accepted]:
            return
 
        # if order.status in [order.Completed]:
        #     if order.isbuy():
        #         self.log(f'买入执行, 价格: {order.executed.price:.2f}, 成本: {order.executed.value:.2f}, 佣金: {order.executed.comm:.2f}')
        #         self.update_stop_loss_take_profit()
        #     elif order.issell():
        #         self.log(f'卖出执行, 价格: {order.executed.price:.2f}, 成本: {order.executed.value:.2f}, 佣金: {order.executed.comm:.2f}')
 
        self.order = None

    # def notify_trade(self, trade):
    #     super().notify_trade(trade)

    def calculate_position_size(self):
        """计算固定风险比例的仓位大小
            本金 * 风险因子 * 现价 / atr
        """
        if self.atr[0] <=0:
            return 0
        account_value = self.broker.getvalue()
        # 风险金额
        risk_amount = account_value * self.p.risk_exposure
        return risk_amount / self.atr[0]

    def next(self):
        super().next()
        print(f"时间：{self.data.datetime.datetime(0)}，收盘价：{self.data.close[0]}，最高价：{self.donchian_high[0]},最低：{self.donchian_low[0]}")
        # 有未完成的订单时, 不进行新订单
        if self.order:
            return
        if not self.position: #没有持仓
            # 计算风险仓位
            size = self.calculate_position_size()
            if size == 0:
                return
            
            #多头信号
            if self.data.close[0] > self.donchian_high[-1]:
                self.order = self.buy(size=size,price=self.data.close[0] * 1.01)
            elif self.data.close[0] < self.donchian_low[-1]:
                self.order = self.sell(size=size,price=self.data.close[0] * 0.99)
        else:# 有持仓
            # 自动计算止盈止损, 最高最低价等
            self.update_stop_loss_take_profit()

            if self.position.size > 0:  # 多头持仓
                if self.data.close[0] <= self.stop_loss_price or self.data.close[0] >= self.take_profit_price:
                    if self.data.close[0] <= self.stop_loss_price:
                        self.log(f'止损触发 - 止损价: {self.stop_loss_price:.2f}, 当前价: {self.data.close[0]:.2f}')
                    else:
                        self.log(f'止盈触发 - 止盈价: {self.take_profit_price:.2f}, 当前价: {self.data.close[0]:.2f}')
                    self.order = self.close()
            else:  # 空头持仓
                if self.data.close[0] >= self.stop_loss_price or self.data.close[0] <= self.take_profit_price:
                    if self.data.close[0] >= self.stop_loss_price:
                        self.log(f'止损触发 - 止损价: {self.stop_loss_price:.2f}, 当前价: {self.data.close[0]:.2f}')
                    else:
                        self.log(f'止盈触发 - 止盈价: {self.take_profit_price:.2f}, 当前价: {self.data.close[0]:.2f}')
                    # self.log(f'止损/止盈触发 - 止损价: {self.stop_loss_price:.2f}, 止盈价: {self.take_profit_price:.2f}, 当前价: {self.data.close[0]:.2f}')
                    self.order = self.close()




    # 更新最高最低价格, 以及移动止盈价格
    def update_stop_loss_take_profit(self):
        if self.position:
            # 更新最高价和最低价
            if self.position.size > 0:  # 多头
                if self.highest_price == 0:
                    self.highest_price = self.data.close[0]
                else:
                    self.highest_price = max(self.highest_price, self.data.high[0])

                self.stop_loss_price = self.entry_price - self.p.stop_loss_mult * self.atr[0]
                
                # 回撤止盈
                trail_stop = self.highest_price - self.p.trail_mult * self.atr[0]
                self.stop_loss_price = max(self.stop_loss_price, trail_stop)
                
                # 盈利止盈
                self.take_profit_price = self.entry_price + self.p.take_profit_mult * self.atr[0]
            else:  # 空头
                if self.lowest_price == 0:
                    self.lowest_price = self.data.close[0]
                else:
                    self.lowest_price = min(self.lowest_price, self.data.low[0])

                self.stop_loss_price = self.entry_price + self.p.stop_loss_mult * self.atr[0]
                
                # 回撤止盈
                trail_stop = self.lowest_price + self.p.trail_mult * self.atr[0]
                self.stop_loss_price = min(self.stop_loss_price, trail_stop)
                
                # 盈利止盈
                self.take_profit_price = self.entry_price - self.p.take_profit_mult * self.atr[0]